package com.songlei.rtcadriondh265demo.rtc

import org.webrtc.Logging
import org.webrtc.VideoFrame
import org.webrtc.VideoSink

/**
 * 视频帧代理接收器，用于将接收到的视频帧动态转发给指定的目标VideoSink。
 * 本类采用代理模式，允许在运行时切换或移除目标VideoSink，并保证线程安全。
 */
class ProxyVideoSink : VideoSink {

    // 使用volatile保证目标对象的可见性，确保多线程环境下目标引用的修改立即可见
    @Volatile
    private var target: VideoSink? = null // 被代理的目标VideoSink，可能动态变化

    /**
     * 视频帧接收回调方法。当有新的视频帧到达时，此方法会被调用。
     * 本方法保证线程安全，同一时间只有一个线程能访问目标对象。
     *
     * @param frame 接收到的视频帧对象。可能为null，但实际通常由WebRTC框架保证非空。
     * 注意：帧对象需要由接收方负责释放，代理不管理资源生命周期。
     */
    @Synchronized
    override fun onFrame(frame: VideoFrame?) {
        // 检查目标是否有效，避免空指针异常
        if (target == null) {
            Logging.d(TAG, "Dropping frame in proxy because target is null. frame_id=${frame?.hashCode()}")
            return
        }

        try {
            // 将视频帧转发给目标接收器
            target!!.onFrame(frame)
        } catch (e: Exception) {
            Logging.e(TAG, "Error forwarding frame to target", e)
        }
    }

    /**
     * 动态设置目标视频接收器。
     * 本方法线程安全，保证设置目标时的原子性操作。
     *
     * @param target 新的目标VideoSink对象。设置为null时后续帧将被丢弃，
     *               可用于实现接收器的动态卸载。
     */
    @Synchronized
    fun setTarget(target: VideoSink?) {
        Logging.d(TAG, "Updating target video sink: ${target?.javaClass?.simpleName}")
        this.target = target
    }

    companion object {
        // 日志标签（注意：实际日志系统可能根据TAG进行分类过滤）
        private const val TAG = "sl_ProxyVideoSink"
    }
}